#ifndef VAR_HEADER_H
#define VAR_HEADER_H
#include <string>
#include <vector>
#include <stdint.h>
#include <stdlib.h>
#include "UEFIHeader.h"
/*
typedef char CHAR8;
typedef char16_t CHAR16;
typedef uint8_t BOOLEAN;
typedef uint8_t UINT8;
typedef uint16_t UINT16;
typedef uint32_t UINT32;
typedef uint64_t UINT64;
*/
#pragma pack(push, 1)
/*
typedef struct {
    UINT32 Data1;
    UINT16 Data2;
    UINT16 Data3;
    UINT8 Data4[8];
} EFI_GUID;
*/
//
// VSS2 variables
//

// aaf32c78-947b-439a-a180-2e144ec37792
#define NVRAM_VSS2_AUTH_VAR_KEY_DATABASE_GUID_PART1 0xaaf32c78
const char NVRAM_VSS2_AUTH_VAR_KEY_DATABASE_GUID[] = 
("\x78\x2C\xF3\xAA\x7B\x94\x9A\x43\xA1\x80\x2E\x14\x4E\xC3\x77\x92");

#define NVRAM_VSS2_STORE_GUID_PART1 0xddcf3617
const char NVRAM_VSS2_STORE_GUID[] = 
("\x17\x36\xCF\xDD\x75\x32\x64\x41\x98\xB6\xFE\x85\x70\x7F\xFE\x7D");

#define NVRAM_FDC_STORE_GUID_PART 0xddcf3616
const char NVRAM_FDC_STORE_GUID[] = 
("\x16\x36\xCF\xDD\x75\x32\x64\x41\x98\xB6\xFE\x85\x70\x7F\xFE\x7D");
///
/// Variable Store region header.
///
typedef struct {
  ///
  /// Variable store region signature.
  ///
  EFI_GUID  Signature;
  ///
  /// Size of entire variable store,
  /// including size of variable store header but not including the size of FvHeader.
  ///
  UINT32  Size;
  ///
  /// Variable region format state.
  ///
  UINT8   Format;
  ///
  /// Variable region healthy state.
  ///
  UINT8   State;
  UINT16  Reserved;
  UINT32  Reserved1;
} VARIABLE_STORE_HEADER;

///
/// Single Variable Data Header Structure.
///

typedef struct {
  ///
  /// Variable Data Start Flag.
  ///
  UINT16      StartId;
  ///
  /// Variable State defined above.
  ///
  UINT8       State;
  UINT8       Reserved;
  ///
  /// Attributes of variable defined in UEFI specification.
  ///
  UINT32      Attributes;
  ///
  /// Size of variable null-terminated Unicode string name.
  ///
  UINT32      NameSize;
  ///
  /// Size of the variable data without this header.
  ///
  UINT32      DataSize;
  ///
  /// A unique identifier for the vendor that produces and consumes this varaible.
  ///
  EFI_GUID    VendorGuid;
} VARIABLE_HEADER;

// EFI Time
typedef struct EFI_TIME_ {
    UINT16  Year;       // Year:       2000 - 20XX
    UINT8   Month;      // Month:      1 - 12
    UINT8   Day;        // Day:        1 - 31
    UINT8   Hour;       // Hour:       0 - 23
    UINT8   Minute;     // Minute:     0 - 59
    UINT8   Second;     // Second:     0 - 59
    UINT8   Reserved0;
    UINT32  Nanosecond; // Nanosecond: 0 - 999,999,999
    UINT16   TimeZone;   // TimeZone:   -1440 to 1440 or UNSPECIFIED (0x07FF)
    UINT8   Daylight;   // Daylight:   ADJUST_DAYLIGHT (1) or IN_DAYLIGHT (2)
    UINT8   Reserved1;
} EFI_TIME;

//typedef struct VSS_AUTH_VARIABLE_HEADER_ {
typedef struct {
    UINT16    StartId;          // Variable start marker AA55
    UINT8     State;            // Variable state
    UINT8     Reserved;
    UINT32    Attributes;       // Variable attributes
    UINT64    MonotonicCounter; // Monotonic counter against replay attack
    EFI_TIME  Timestamp;        // Time stamp against replay attack
    UINT32    PubKeyIndex;      // Index in PubKey database
    UINT32    NameSize;         // Size of variable name, stored as null-terminated UCS2 string
    UINT32    DataSize;         // Size of variable data without header and name
    EFI_GUID  VendorGuid;       // Variable vendor GUID
} AUTH_VARIABLE_HEADER;
//} VSS_AUTH_VARIABLE_HEADER;

typedef struct {
  ///
  /// The number of sequential blocks which are of the same size.
  ///
  UINT32 NumBlocks;
  ///
  /// The size of the blocks.
  ///
  UINT32 Length;
} EFI_FV_BLOCK_MAP_ENTRY;
///
/// type of EFI FVB attribute
///
typedef UINT32  EFI_FVB_ATTRIBUTES_2;
///
/// Describes the features and layout of the firmware volume.
///
typedef struct {
  ///
  /// The first 16 bytes are reserved to allow for the reset vector of
  /// processors whose reset vector is at address 0.
  ///
  UINT8                     ZeroVector[16];
  ///
  /// Declares the file system with which the firmware volume is formatted.
  ///
  EFI_GUID                  FileSystemGuid;
  ///
  /// Length in bytes of the complete firmware volume, including the header.
  ///
  UINT64                    FvLength;
  ///
  /// Set to EFI_FVH_SIGNATURE
  ///
  UINT32                    Signature;
  ///
  /// Declares capabilities and power-on defaults for the firmware volume.
  ///
  EFI_FVB_ATTRIBUTES_2      Attributes;
  ///
  /// Length in bytes of the complete firmware volume header.
  ///
  UINT16                    HeaderLength;
  ///
  /// A 16-bit checksum of the firmware volume header. A valid header sums to zero.
  ///
  UINT16                    Checksum;
  ///
  /// Offset, relative to the start of the header, of the extended header
  /// (EFI_FIRMWARE_VOLUME_EXT_HEADER) or zero if there is no extended header.
  ///
  UINT16                    ExtHeaderOffset;
  ///
  /// This field must always be set to zero.
  ///
  UINT8                     Reserved[1];
  ///
  /// Set to 2. Future versions of this specification may define new header fields and will
  /// increment the Revision field accordingly.
  ///
  UINT8                     Revision;
  ///
  /// An array of run-length encoded FvBlockMapEntry structures. The array is
  /// terminated with an entry of {0,0}.
  ///
  EFI_FV_BLOCK_MAP_ENTRY    BlockMap[1];
} EFI_FIRMWARE_VOLUME_HEADER;

typedef union {
    struct {
        UINT8 Header;
        UINT8 File;
    } Checksum;
    UINT16 TailReference;   // Revision 1
    UINT16 Checksum16;      // Revision 2
} EFI_FFS_INTEGRITY_CHECK;

typedef struct EFI_FFS_FILE_HEADER_ {
    EFI_GUID                Name;
    EFI_FFS_INTEGRITY_CHECK IntegrityCheck;
    UINT8                   Type;
    UINT8                   Attributes;
    UINT8                   Size[3];
    UINT8                   State;
} EFI_FFS_FILE_HEADER;

typedef struct NVAR_ENTRY_HEADER_ {
    UINT32 Signature;      // NVAR
    UINT16 Size;           // Size of the entry including header
    UINT32 Next : 24;      // Offset to the next entry in a list, or empty if the latest in the list
    UINT32 Attributes : 8; // Attributes
    UINT8  u8Index;
    char  Name[0];
} NVAR_ENTRY_HEADER;
#define NVRAM_NVAR_ENTRY_SIGNATURE     0x5241564E //NVAR

#define NVRAM_NVAR_ENTRY_RUNTIME           0x01
#define NVRAM_NVAR_ENTRY_DATA_ONLY         0x08

#pragma pack(pop)
#define EFI_FVH_SIGNATURE SIGNATURE_32 ('_', 'F', 'V', 'H')

#endif
